import subprocess
from flask import Flask, jsonify, request, redirect, send_file
from virtual import Virtual
from flask_cors import CORS  # 导入 CORS 模块
import xml.etree.ElementTree as ET

app = Flask(__name__, static_folder='page', static_url_path='/page')
CORS(app)  # 为应用启用 CORS，允许所有来源的跨域请求
virt = Virtual()

def websockify():
    # 启动 websockify 进程
    try:
        websockify_process = subprocess.Popen([
            "python",
            "-m",
            "websockify",
            '--token-plugin=BaseTokenAPI',
            '--token-source=http://localhost:5000/token?token=%s',
            '8009'
        ], cwd="./websockify")
        print("Websockify 已启动")
    except Exception as e:
        print(f"启动 Websockify 时出错: {e}")
        if 'websockify_process' in locals():
            websockify_process.terminate()

@app.route('/')
def index():
    """
    返回主页
    """
    return redirect("page/index.html", code=302)

@app.route('/index.html')
def home():
    """
    返回主页
    """
    return redirect("page/index.html", code=302)

@app.route('/vms', methods=['GET'])
def get_all_vms():
    """
    获取所有虚拟机的信息
    """
    vms = virt.get_all_vms()
    return jsonify(vms)

@app.route('/vms/<vm_name>/state', methods=['GET'])
def get_vm_state(vm_name):
    """
    获取指定虚拟机的状态
    """
    state = virt.get_vm_state(vm_name)
    return jsonify({'state': state})

@app.route('/vms/<vm_name>/start', methods=['POST'])
def start_vm(vm_name):
    """
    启动指定虚拟机
    """
    try:
        result = virt.start_vm(vm_name)
        return jsonify({'success': result})
    except Exception as e:
        print(f"启动虚拟机时出错: {e}")
        return jsonify({'error': str(e)}), 500

@app.route('/vms/<vm_name>/shutdown', methods=['POST'])
@app.route('/vms/<vm_name>/force-shutdown', methods=['POST'])
def force_shutdown_vm(vm_name):
    """
    强制关闭指定虚拟机
    """
    try:
        result = virt.force_shutdown_vm(vm_name)
        return jsonify({'success': result})
    except Exception as e:
        print(f"强制关闭虚拟机时出错: {e}")
        return jsonify({'error': str(e)}), 500

@app.route('/vms/<vm_name>/suspend', methods=['POST'])
def suspend_vm(vm_name):
    """
    暂停指定虚拟机
    """
    try:
        # 直接调用虚拟机的暂停方法
        result = virt.suspend_vm(vm_name)
        return jsonify({'success': result})
    except Exception as e:
        print(f"暂停虚拟机时出错: {e}")
        return jsonify({'error': str(e)}), 500

@app.route('/vms/<vm_name>/delete', methods=['POST'])
def delete_vm(vm_name):
    """
    删除指定虚拟机，支持传递要删除的磁盘列表
    """
    data = request.get_json()
    disks_to_delete = data.get('disks', [])
    try:
        result = virt.delete_vm(vm_name, disks_to_delete)
        return jsonify({'success': result})
    except Exception as e:
        print(f"删除虚拟机时出错: {e}")
        return jsonify({'error': str(e)}), 500

@app.route('/vms/clone', methods=['POST'])
def clone_vm():
    """
    克隆虚拟机
    """
    data = request.get_json()
    source_vm_name = data.get('source_vm_name')
    clone_vm_name = data.get('clone_vm_name')
    if not source_vm_name or not clone_vm_name:
        return jsonify({'error': 'Missing source_vm_name or clone_vm_name'}), 400
    result = virt.clone_vm(source_vm_name, clone_vm_name)
    return jsonify({'success': result})

@app.route('/vms/create', methods=['POST'])
def create_vm():
    """
    根据提供的 XML 描述创建虚拟机
    """
    data = request.get_json()
    xml_desc = data.get('xml_desc')
    if not xml_desc:
        return jsonify({'error': 'Missing xml_desc'}), 400
    result = virt.create_vm(xml_desc)
    return jsonify({'success': result})

@app.route('/token', methods=['GET'])
def token():
    """
    验证 token 是否有效并返回解密后的端口
    """
    token = request.args.get('token')
    if not token:
        return ""

    try:
        # 直接调用解码方法
        decrypted_port = virt._decrypt_port(token)
        if decrypted_port:
            return f"localhost:{decrypted_port}"
        return ""
    except Exception as e:
        print(f"端口解密失败: {e}")
        return ""

# 新增接口来获取 KVM 网络接口
@app.route('/kvm/networks', methods=['GET'])
def get_kvm_networks():
    """
    获取 KVM 网络接口信息
    """
    try:
        # 假设 Virtual 类中有 get_kvm_networks 方法来获取网络接口信息
        networks = virt.get_kvm_networks()
        return jsonify(networks)
    except Exception as e:
        print(f"获取 KVM 网络接口信息时出错: {e}")
        return jsonify({'error': str(e)}), 500

@app.route('/libvirt/images', methods=['GET'])
def get_libvirt_images():
    """
    获取 /var/lib/libvirt 目录下镜像的详细信息
    """
    try:
        images = virt.get_libvirt_images()
        return jsonify(images)
    except Exception as e:
        print(f"获取镜像信息时出错: {e}")
        return jsonify({'error': str(e)}), 500

if __name__ == '__main__':
    websockify()
    app.run(debug=False, host='0.0.0.0')
